package controller

import (
	"fmt"
	"path"
	"strconv"

	"device-admin/internal/app/grpc/service/terminal"

	"192.168.1.75/go-pkg/response"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type Teleport struct{}

// Get95FileInfo 获取95文件的信息
func (Teleport) Get95FileInfo(c *gin.Context) {
	robotID := c.Query("robot_id") // 设备id
	fileURL := c.Query("file_url") // 文件url地址
	fileSize, err := terminal.GetTerminalFileInfo(robotID, "webshell95", fileURL)
	response.JSON(c, map[string]interface{}{
		"file_size": fileSize,
	}, err)
}

// Download95File 下载95文件
func (Teleport) Download95File(c *gin.Context) {
	robotID := c.Query("robot_id") // 设备id
	fileURL := c.Query("file_url") // 文件url地址
	fileSize, err := terminal.GetTerminalFileInfo(robotID, "webshell95", fileURL)
	if err != nil || fileSize == 0 {
		c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", "获取文件失败.html"))
		c.Header("Content-Type", "text/html")
		c.Writer.Write([]byte(""))
	} else {
		// 设置响应头
		c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", path.Base(fileURL)))
		c.Header("Content-Length", strconv.FormatInt(fileSize, 10))
		// 分批次读取文件内容，每次300KB，并将结果写入到缓冲区中
		chunkSize := int64(300 * 1024)
		for size := int64(0); size < fileSize; size += chunkSize {
			select {
			case <-c.Request.Context().Done():
				return
			default:
				content, err := terminal.GetTerminalFileContent(robotID, "webshell95", fileURL, size, chunkSize)
				if err != nil {
					return
				}
				if len(content) > 0 {
					c.Writer.Write(content)
				}
			}
		}
	}
}

type Screencap struct{}

// Cap 进行一次屏幕截图
func (Screencap) Cap(c *gin.Context) {
	var params struct {
		RobotID      string `json:"robot_id"`
		TerminalType string `json:"terminal_type"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	url, err := terminal.Screencap(c.Request.Context(), params.RobotID, params.TerminalType, c.GetString("user_id"))
	response.JSON(c, map[string]interface{}{
		"url": url,
	}, err)
}

// List 屏幕截图列表
func (Screencap) List(c *gin.Context) {
	page := -1
	limit := -1
	if pageStr, exists := c.GetQuery("page"); exists {
		page, _ = strconv.Atoi(pageStr)
	}
	if limitStr, exists := c.GetQuery("limit"); exists {
		limit, _ = strconv.Atoi(limitStr)
	}
	list, total, err := terminal.ScreencapList(
		c.Request.Context(),
		c.Query("robot_id"),
		c.Query("terminal_type"),
		page,
		limit,
	)
	response.JSON(c, map[string]interface{}{
		"list":  list,
		"total": total,
	}, err)
}

type ScreenCapURI struct {
	RobotID       string `uri:"robot_id"`       // 设备id
	ScreenCapDir  string `uri:"screencap_dir"`  // 截图存放的目录
	ScreenCapName string `uri:"screencap_name"` // 截图的名称
}

// pic 获取截图图片
func (Screencap) Pic(c *gin.Context) {
	var params ScreenCapURI
	c.ShouldBindUri(&params)
	content, _ := terminal.ScreencapPic(
		c.Request.Context(),
		params.RobotID,
		"./"+params.ScreenCapDir+"/"+params.ScreenCapName,
	)
	c.Header("content-type", "image/png")
	c.Header("Content-Length", strconv.Itoa(len(content)))
	c.Writer.Write(content)
}
